#include <stdio.h>
#include <string.h>
#define ZERO 0
char* mystrcpy(char *dest, const char *src);
char* mystrncpy(char *dest, const char *src, size_t n);
char *mystrcat(char *dest, const char *src);
char *mystrncat(char *dest, const char *src, size_t n);
int mystrcmp(const char *s1, const char *s2);
int mystrncmp(const char *s1, const char *s2, size_t n);
void *mymemset(void *s, int c, size_t n);
void *mymemmove(void *dst, const void *src, size_t n);
void *mymemcpy(void *dst, const void *src, size_t n) ;
int mymemcmp(const void *s1, const void *s2, size_t n);

void print_array(int* arr, int n) ;
void int_arr_copy_test();
void char_arr_copy_test() ;
int main(void)
{
   char str1[10]="1123 4ord";
   char str2[10]="1123 3";
//     int  array[10];

//     mymemset(array,-1,sizeof(array));
//     for(int i=0;i<10;i++)
//         printf("array[%d] is :%08x\n",i,array[i]);
   int cmp_str,cmp_mem;
   cmp_str = mystrncmp(str1,str2,strlen(str2));
   cmp_mem = mymemcmp(str1,str2,strlen(str2));
   printf("str1=%s, str2=%s\ncmp_str=%d cmp_mem=%d\n",str1,str2,cmp_str,cmp_mem); 
    // int_arr_copy_test();
    // char_arr_copy_test();
    return 0;
}
char* mystrncpy(char *dest, const char *src, size_t n)
{
    size_t i;
    for (i = 0; i < n && src[i] != '\0'; i++)
        dest[i] = src[i];
    for ( ; i < n; i++)
        dest[i] = '\0';
    return dest;
}
char* mystrcpy(char *dest, const char *src)
{
    size_t i;
    for (i = 0; src[i] != '\0'; i++)
    {
        dest[i] = src[i];
    }
        dest[i] = '\0';
    return dest;
}
char *mystrcat(char *dest, const char *src)
{
    size_t dest_len = strlen(dest);
    size_t i ;
    for(i=0;*(src+i)!='\0';i++)
    {
        *(dest+dest_len+i)=*(src+i);  
    }
    *(dest+dest_len+i)='\0';  
    return dest;
}
char *mystrncat(char *dest, const char *src, size_t n)
{
    size_t dest_len = strlen(dest);
    size_t i ;
    for(i=0;i<n && *(src+i)!='\0';i++)
    {
        *(dest+dest_len+i)=*(src+i);  
    }
    *(dest+dest_len+i)='\0';  
    return dest;
}

int mystrcmp(const char *s1, const char *s2)
{
    while(*s1 == *s2 && *s1!='\0')
    {
        s1++;
        s2++;
    }
    return (*s1 - *s2);
}

int mystrncmp(const char *s1, const char *s2, size_t n)
{
    // --n是先减后判断，n++是先判断完再减
    while(*s1 == *s2 && *s1!='\0' && --n)
    {
        s1++;
        s2++;
    }
    return (*s1 - *s2);
}

void *mymemset(void *s, int c, size_t n) {
    // The range of c is 0 to 255

    char*tmp_s = (char*)s;//需要返回原指针
    unsigned char realc=(unsigned char)c;
    while(n--)
    {
        *tmp_s = realc;
        tmp_s++;
    }
    return s;
}

void *mymemmove(void *dst, const void *src, size_t n) {
    char*dst_tmp = (char*)dst;
    char*src_tmp = (char*)src;
    if (dst_tmp<src_tmp)
        while(n--)
        {
            *dst_tmp = *src_tmp;
            dst_tmp++;
            src_tmp++;
        }
    else
        while(n--)
        {
            *(dst_tmp+n) = *(src_tmp+n);
        }    
    return dst;
}
void *mymemcpy(void *dst, const void *src, size_t n) {
    char*dst_tmp = (char*)dst;
    char*src_tmp = (char*)src;
        while(n--)
        {
            *dst_tmp = *src_tmp;
            dst_tmp++;
            src_tmp++;
        }   
    return dst;
}
int mymemcmp(const void *s1, const void *s2, size_t n){
    // --n是先减后判断，n++是先判断完再减
    char*s1_tmp = (char*)s1;
    char*s2_tmp = (char*)s2;

    while(*s1_tmp == *s2_tmp && --n)
    {
        s1_tmp++;
        s2_tmp++;
    }
    return (*s1_tmp - *s2_tmp);
}
// 打印数组函数
void print_array(int* arr, int n) {
    if (arr == NULL) { // C语言用 NULL，C++11用nullptr
        return;
    }
    for (int i = 0; i < n; i++){
        printf("%d ", arr[i]);
    }
    printf("\n");
}
// int 类型对象占 4 个字节
void int_arr_copy_test() {
    int arr[] = {1,2,3,4,5,6,7,8,9}; // int 数组
    print_array(arr, 9);
    // std::memmove(arr + 4, arr + 3, sizeof(int)); // 从 [4, 5, 6] 复制到 [5, 6, 7]
    mymemmove(arr , arr + 5, 8); 
    print_array(arr, 9);
}
// char 类型对象占 1 个字节
void char_arr_copy_test() {
    char str[] = "1234567890"; // char 数组
    puts (str);
    // std::cout << str << '\n';
     mymemcpy(str +2 , str, 4); 
    puts (str);

}